class TechnicalAnalysis {
  // 分析趋势
  static analyzeTrend(klineData) {
    if (!klineData || klineData.length < 20) {
      return {
        trend: '数据不足',
        strength: 0,
        details: {
          priceChange: '0%',
          ma5Trend: '无',
          ma10Trend: '无'
        }
      };
    }

    // 计算MA5、MA10和MA20
    const ma5Array = TechnicalAnalysis.calculateMA(5, klineData);
    const ma10Array = TechnicalAnalysis.calculateMA(10, klineData);
    const ma20Array = TechnicalAnalysis.calculateMA(20, klineData);

    if (!ma5Array || !ma10Array || !ma20Array) {
      return {
        trend: '数据不足',
        strength: 0,
        details: {
          priceChange: '0%',
          ma5Trend: '无',
          ma10Trend: '无'
        }
      };
    }

    // 获取最新的MA值
    const ma5 = ma5Array[ma5Array.length - 1];
    const ma10 = ma10Array[ma10Array.length - 1];
    const ma20 = ma20Array[ma20Array.length - 1];

    // 计算最近5天的价格变化
    const recentPrices = klineData.slice(-5);
    const priceChange = ((recentPrices[recentPrices.length - 1].close - recentPrices[0].close) / recentPrices[0].close * 100).toFixed(1);

    // 计算MA趋势
    const ma5Trend = TechnicalAnalysis.calculateMATrend(ma5Array.slice(-3));
    const ma10Trend = TechnicalAnalysis.calculateMATrend(ma10Array.slice(-3));
    const ma20Trend = TechnicalAnalysis.calculateMATrend(ma20Array.slice(-3));

    // 计算综合趋势强度
    let strength = 0;
    
    // MA趋势权重（60%）
    if (ma5 > ma10 && ma10 > ma20) {
      strength += 0.6;
    } else if (ma5 < ma10 && ma10 < ma20) {
      strength -= 0.6;
    }

    // 近期价格变化权重（40%）
    strength += (parseFloat(priceChange) / 100) * 0.4;

    // 确定趋势描述
    let trend = '';
    if (strength >= 0.8) {
      trend = '强势上涨';
    } else if (strength >= 0.3) {
      trend = '温和上涨';
    } else if (strength <= -0.8) {
      trend = '强势下跌';
    } else if (strength <= -0.3) {
      trend = '温和下跌';
    } else {
      trend = '横盘整理';
    }

    return {
      trend: trend,
      strength: strength,
      details: {
        priceChange: priceChange + '%',
        ma5Trend: TechnicalAnalysis.getTrendDescription(ma5Trend),
        ma10Trend: TechnicalAnalysis.getTrendDescription(ma10Trend)
      }
    };
  }

  static calculateMATrend(maValues) {
    if (maValues.length < 2) return 0;
    return (maValues[maValues.length - 1] - maValues[0]) / maValues[0];
  }

  static getTrendDescription(trend) {
    if (trend > 0.01) return '上升';
    if (trend < -0.01) return '下降';
    return '平稳';
  }

  // 计算移动平均线
  static calculateMA(period, data) {
    if (!data || data.length < period) return null;
    
    const prices = data.map(item => parseFloat(item.close));
    const result = [];
    
    // 计算移动平均线数组
    for (let i = period - 1; i < prices.length; i++) {
      const sum = prices.slice(i - period + 1, i + 1).reduce((a, b) => a + b, 0);
      result.push(sum / period);
    }
    
    return result;
  }

  // 计算RSI
  static calculateRSI(data, period = 14) {
    if (!data || data.length < period + 1) return null;
    
    let gains = 0;
    let losses = 0;
    
    // 计算指定周期的涨跌
    for (let i = data.length - period; i < data.length; i++) {
      const change = parseFloat(data[i].close) - parseFloat(data[i - 1].close);
      if (change >= 0) {
        gains += change;
      } else {
        losses -= change;
      }
    }
    
    const avgGain = gains / period;
    const avgLoss = losses / period;
    
    if (avgLoss === 0) return 100;
    
    const rs = avgGain / avgLoss;
    return 100 - (100 / (1 + rs));
  }

  // 计算MACD
  static calculateMACD(data) {
    if (!data || data.length < 26) return null;
    
    const prices = data.map(item => parseFloat(item.close));
    const ema12 = TechnicalAnalysis.calculateEMA(prices, 12);
    const ema26 = TechnicalAnalysis.calculateEMA(prices, 26);
    
    if (!ema12 || !ema26) return null;
    
    return ema12 - ema26;
  }

  // 计算EMA
  static calculateEMA(prices, period) {
    if (!prices || prices.length < period) return null;
    
    const k = 2 / (period + 1);
    let ema = prices.slice(0, period).reduce((a, b) => a + b) / period;
    
    for (let i = period; i < prices.length; i++) {
      ema = (prices[i] - ema) * k + ema;
    }
    
    return ema;
  }

  // 评估风险
  static assessRisk(klineData, technicalData) {
    if (!klineData || !technicalData) {
      return {
        level: '无法评估',
        score: 0,
        details: {
          volatility: 0,
          volume: '数据不足',
          trend: '数据不足'
        }
      };
    }

    // 计算波动率
    const volatility = TechnicalAnalysis.calculateVolatility(klineData);
    
    // 分析成交量趋势
    const volumeTrend = TechnicalAnalysis.analyzeVolumeTrend(klineData);
    
    // 分析价格趋势
    const priceTrend = TechnicalAnalysis.analyzeTrend(klineData);
    
    // 计算综合风险分数
    let riskScore = 0;
    
    // 波动率权重 40%
    riskScore += (volatility > 3 ? 40 : volatility / 3 * 40);
    
    // 成交量趋势权重 30%
    if (volumeTrend === '放量上涨') riskScore += 15;
    else if (volumeTrend === '放量下跌') riskScore += 30;
    else if (volumeTrend === '缩量上涨') riskScore += 20;
    else if (volumeTrend === '缩量下跌') riskScore += 25;
    
    // 价格趋势权重 30%
    if (priceTrend.trend.includes('强势上涨')) riskScore += 30;
    else if (priceTrend.trend.includes('温和上涨')) riskScore += 20;
    else if (priceTrend.trend.includes('强势下跌')) riskScore += 25;
    else if (priceTrend.trend.includes('温和下跌')) riskScore += 15;
    else riskScore += 10;
    
    // 确定风险等级
    let riskLevel = '';
    if (riskScore >= 80) riskLevel = '极高风险';
    else if (riskScore >= 60) riskLevel = '高风险';
    else if (riskScore >= 40) riskLevel = '中等风险';
    else riskLevel = '低风险';
    
    return {
      level: riskLevel,
      score: riskScore,
      details: {
        volatility: volatility.toFixed(2),
        volume: volumeTrend,
        trend: priceTrend.trend
      }
    };
  }

  // 计算波动率
  static calculateVolatility(data) {
    if (!data || data.length < 2) return 0;
    
    const returns = [];
    for (let i = 1; i < data.length; i++) {
      const prev = parseFloat(data[i - 1].close);
      const curr = parseFloat(data[i].close);
      returns.push((curr - prev) / prev * 100);
    }
    
    const mean = returns.reduce((a, b) => a + b, 0) / returns.length;
    const variance = returns.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / returns.length;
    return Math.sqrt(variance);
  }

  // 分析成交量趋势
  static analyzeVolumeTrend(data) {
    if (!data || data.length < 5) return '数据不足';
    
    const volumes = data.map(item => parseInt(item.volume));
    const prices = data.map(item => parseFloat(item.close));
    
    // 计算最近5天的平均成交量
    const recentAvgVolume = volumes.slice(-5).reduce((a, b) => a + b, 0) / 5;
    // 计算之前5天的平均成交量
    const prevAvgVolume = volumes.slice(-10, -5).reduce((a, b) => a + b, 0) / 5;
    
    // 判断价格趋势
    const priceChange = (prices[prices.length - 1] - prices[prices.length - 5]) / prices[prices.length - 5] * 100;
    
    // 判断成交量变化
    const volumeChange = (recentAvgVolume - prevAvgVolume) / prevAvgVolume * 100;
    
    if (volumeChange > 20 && priceChange > 0) return '放量上涨';
    if (volumeChange > 20 && priceChange < 0) return '放量下跌';
    if (volumeChange < -20 && priceChange > 0) return '缩量上涨';
    if (volumeChange < -20 && priceChange < 0) return '缩量下跌';
    return '成交量平稳';
  }
}

module.exports = TechnicalAnalysis; 